/**
  ******************************************************************************
  * @file    command_line.h
  * @author  ashuai0110
  * @version V2.3
  * @date    2024-07-01
  * @brief   命令行交互
  *          (类命令行,空格分割 比如:cmd arg1 arg2\r\n或AT+CMD= arg1 arg2\r\n)
  *
  ******************************************************************************
  * @attention
  *
  * 版权声明:内容为编者(ashuai0110)原创,使用请注明出处,当然,你也可以不这样做^_^
  * 出处链接:https://gitee.com/ashuai0110/mcu_reuse_development_module.git
  *
  ******************************************************************************
  */

#ifndef __COMMAND_LINE_H
#define __COMMAND_LINE_H

#ifdef __cplusplus
extern "C" {
#endif

/* 包含头文件-----------------------------------------------------------------*/
#include "common_include.h"

/**
 * @addtogroup modules
 * @{
 */

/**
 * @addtogroup command_line
 * @{
 */

/* 宏定义---------------------------------------------------------------------*/
/**
 * @defgroup command_line_global_macros command line global macros
 * @{
 */

/**
 * @defgroup cmd_line_parameters command line parameters
 * @{
 */
#define CMD_LINE_LEN_MAX                (255u) /*!< 命令行一次输入最大长度 用户按需修改 */
#define CMD_LINE_ARG_MAX                (8u)   /*!< 命令行一次输入最多参数个数 用户按需修改 */
#define CMD_LINE_SAVE_MAX               (16u)  /*!< 存储命令最多条数 用户按需修改 */
#define CMD_LINE_NAME_MAX               (12u)  /*!< 命令名称最大长度 用户按需修改 */
#define CMD_LINE_SPLIT_SYMBOL           (' ')  /*!< 分隔符 用户按需修改 */
#define CMD_LINE_END_SYMBOL1            ('\r') /*!< 结束符1 用户按需修改 */
#define CMD_LINE_END_SYMBOL2            ('\n') /*!< 结束符2 用户按需修改 */
/**
 * @}
 */

/**
 * @defgroup cmd_line_echo_flg command line echo flag
 * @{
 */
#define CMD_LINE_ECHO_OFF               (0u) /*!< 关闭回显 */
#define CMD_LINE_ECHO_ON                (1u) /*!< 开启回显 */
/**
 * @}
 */

/**
 * @defgroup cmd_line_run_flg command line run flag
 * @{
 */
#define CMD_LINE_RUN_STOP               (0u) /*!< 不运行 */
#define CMD_LINE_RUN_START              (1u) /*!< 运行 */
/**
 * @}
 */

/**
 * @}
 */

/* 类型定义-------------------------------------------------------------------*/
/**
 * @defgroup command_line_global_types command line global types
 * @{
 */

/**
  * @brief  写入数据 / 读取数据
  *
  * @param  pBuf : 写入数据的存储区 / 读取数据的存储区
  *
  * @param  size : 写入的数据大小 / 读取的数据大小 byte
  *
  * @retval 实际写入的数据大小 / 实际读取的数据大小 byte
  */
typedef uint32_t (* cmd_line_rw_fn_t)(void *pBuf, uint32_t size);

/** 
  * @brief  命令行 structure definition
  */
typedef struct cmd_line {
    char dataArr[CMD_LINE_LEN_MAX]; /*!< 数据暂存区 */
    volatile uint16_t dataCnt;      /*!< 数据计数 */
    uint8_t echoFlg : 1;            /*!< 回显标志 @ref cmd_line_echo_flg */
    uint8_t runFlg : 1;             /*!< 运行标志 @ref cmd_line_run_flg */
    cmd_line_rw_fn_t readFn;        /*!< 数据读函数 */
    cmd_line_rw_fn_t writeFn;       /*!< 数据写函数 */
    struct cmd_line* pNext;         /*!< 下一节点 */
} cmd_line_t;

/**
  * @brief  命令处理
  *
  * @param  _cmd : 命令行实例
  *
  * @param  argc : 参数个数
  *
  * @param  argv : 参数数据
  *
  * @retval None
  */
typedef void (* cmd_line_callback_fn_t)(cmd_line_t *_cmd, int argc, char *argv[]);

/** 
  * @brief  命令项 structure definition
  */
typedef struct cmd_line_item{
    char cmdName[CMD_LINE_NAME_MAX + 1];  /*!< 命令名称 */
    cmd_line_callback_fn_t cmdCallbackFn; /*!< 命令处理回调函数 */
} cmd_line_item_t;

/**
 * @}
 */

/* 全局变量-------------------------------------------------------------------*/

/* 函数原型-------------------------------------------------------------------*/
/**
 * @addtogroup command_line_global_functions
 * @{
 */

uint8_t cmd_line_init(cmd_line_t *_cmd, cmd_line_rw_fn_t writeFn, cmd_line_rw_fn_t readFn, uint8_t echoFlg, uint8_t runFlg);
void cmd_line_de_init(cmd_line_t *_cmd);

uint8_t cmd_line_register(const char *name, cmd_line_callback_fn_t callback);
void cmd_line_printf(cmd_line_t *_cmd, const char *format, ...);

void cmd_line_poll(void);

/* list interface */
uint8_t cmd_line_insert(cmd_line_t *_cmd);
uint8_t cmd_line_pending(cmd_line_t *_cmd);

/* set/get interface */
void cmd_line_set_echo_flg(cmd_line_t *_cmd, uint8_t echoFlg);
uint8_t cmd_line_get_echo_flg(cmd_line_t *_cmd);
void cmd_line_set_run_flg(cmd_line_t *_cmd, uint8_t runFlg);
uint8_t cmd_line_get_run_flg(cmd_line_t *_cmd);

/**
 * @}
 */

/**
 * @}
 */

/**
 * @}
 */

#ifdef __cplusplus
}
#endif

#endif /* command_line.h */
